import sys
import time
from selenium import webdriver
from selenium.webdriver import ActionChains, Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.chrome.service import Service
from selenium_frame import logger


class LiziDriver():
    # 初始化
    def __init__(self, browser=None, driver_path=None):
        self.driver = None
        self.logger = logger
        # 初始化driver
        if "chrome" == browser.lower():
            options = webdriver.ChromeOptions()
            options.add_experimental_option('detach', True)  # 设置浏览器不关闭
            service = Service(executable_path=driver_path)  # Service对象设置浏览器驱动地址
            self.driver = webdriver.Chrome(service=service, options=options)  # 创建WebDriver实例
        elif "firefox" == browser.lower():
            ff_options = webdriver.FirefoxOptions()
            ff_service = Service(executable_path=driver_path)
            self.driver = webdriver.Firefox(service=ff_service, options=ff_options)
        else:
            self.logger.error("请输入正确的浏览器名chrome或firefox，当前输入浏览器名为：{}".format(browser))
            self.logger.error("请输入正确浏览器驱动地址，当前输入浏览器驱动地址为：{}".format(driver_path))
            sys.exit(1)  # 退出程序
        self.driver.maximize_window()  # 窗口最大化

    # 页面跳转
    def navi_to_page(self, url):
        try:
            self.driver.get(url)
        except Exception as e:
            self.logger.error("页面跳转出现异常，url是：{}".format(url))
            self.driver.quit()
            sys.exit(1)

    # 显式等待：等待元素在html中
    def wait_element(self, xpath, second=10):
        locator = (By.XPATH, xpath)
        try:
            element = WebDriverWait(self.driver, second).until(expected_conditions.presence_of_element_located(locator))
        except Exception as e:
            self.logger.error("显式等待元素超时，元素xpath是：{}".format(xpath))
            element = None
        return element

    # 显式等待：等待元素在html中，且可见
    def wait_element_visibility(self, xpath, second=10):
        locator = (By.XPATH, xpath)
        try:
            element = WebDriverWait(self.driver, second).until(
                expected_conditions.visibility_of_element_located(locator))
        except Exception as e:
            self.logger.error("显式等待元素超时，元素xpath是：{}".format(xpath))
            element = None
        return element

    # 强制等待
    def sleep(self, second=1):
        time.sleep(second)

    # 点击
    def click(self, xpath):
        element = self.wait_element(xpath)
        if element is None:
            return "FAIL"
        else:
            element.click()
            return "PASS"

    # 等待元素可见并点击
    def click_visibility(self, xpath):
        element = self.wait_element_visibility(xpath)
        if element is None:
            return "FAIL"
        else:
            element.click()
            return "PASS"

    # 点击Enter键
    def click_enter(self, xpath):
        element = self.wait_element(xpath)
        if element is None:
            return "FAIL"
        else:
            element.send_keys(Keys.ENTER)
            return "PASS"

    # 输入
    def sendkeys(self, xpath, contents):
        element = self.wait_element(xpath)
        if element is None:
            return "FAIL"
        else:
            element.send_keys(contents)
            return "PASS"

    # 清空并输入
    def clear_and_sendkeys(self, xpath, contents):
        element = self.wait_element(xpath)
        if element is None:
            return "FAIL"
        else:
            element.clear()
            element.send_keys(contents)
            return "PASS"

    # iframe切换
    def switch_to_iframe(self, xpath):
        iframe = self.wait_element(xpath)
        if iframe is None:
            return "FAIL"
        else:
            self.driver.switch_to.frame(iframe)
            return "PASS"

    # 从iframe切换回主文档
    def switch_to_default(self):
        self.driver.switch_to.default_content()

    # 窗口切换
    def switch_to_window(self, title):
        flag = False
        # 获取窗口句柄
        handles = self.driver.window_handles
        for handle in handles:
            # 切换窗口
            self.driver.switch_to.window(handle)
            # 根据title判断切换窗口是否是所需要的
            if title in self.driver.title:
                flag = True
                break
            else:
                continue
        if flag:
            return "PASS"
        else:
            self.logger.error("切换窗口失败，窗口title是：{}".format(title))
            return "FAIL"

    # 获取文本
    def get_text(self, xpath):
        element = self.wait_element(xpath)
        if element is None:
            text = None
        else:
            text = element.get_attribute("innerText")
        return text

    # 获取title
    def get_title(self):
        title = self.driver.title
        return title

    # 断言
    def assert_result(self, type, expected, actual):
        """
        type: 断言类型。assertEqual、assertNotEqual、assertContain
        """
        if type == "assertEqual":
            try:
                assert expected == actual
                return "PASS"
            except Exception:
                return "FAIL"
        elif type == "assertUnequal":
            try:
                assert expected != actual
                return "PASS"
            except Exception:
                return "FAIL"
        elif type == "assertContain":
            try:
                assert expected in actual
                return "PASS"
            except Exception:
                return "FAIL"
        else:
            self.logger.error("断言类型错误，类型仅包含：assertEqual、assertNotEqual、assertContain")
            return "FAIL"

    # 关闭当前窗口
    def close(self):
        self.driver.close()

    # 关闭所有窗口，退出驱动
    def quit(self):
        self.driver.quit()

    # 悬停
    def hover(self, xpath):
        element = self.wait_element(xpath)
        if element is None:
            return "FAIL"
        else:
            ActionChains(self.driver).move_to_element(element).perform()
            return "PASS"

    # 刷新
    def refresh(self):
        self.driver.refresh()

    # 停止页面加载
    def stop_page_load(self):
        self.driver.execute_script("window.stop();")
